package org.tinygroup.database.initdata.impl;

import org.tinygroup.database.config.table.Table;
import org.tinygroup.database.config.table.TableField;
import org.tinygroup.database.util.DataBaseUtil;
import org.tinygroup.metadata.config.stdfield.StandardField;
import org.tinygroup.metadata.util.MetadataUtil;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by wangwy11342 on 2016/8/15.
 */
public class OracleInitDataSqlProcessorImpl extends InitDataSqlProcessorImpl{
    private String procSql = "";

    //确保自增长安全调用的存储过程
    private static final String PROC_AUTO_INCREMENT_SQL = "create or replace procedure proc_seq_to_safe" +
            "(v_seqname varchar2,v_tablename varchar2,v_auto_key varchar2) as\n" +
            "  cur_next number(10);\n" +
            "  tsql varchar2(100);\n" +
            "  db_now_max number(10);\n" +
            "begin\n" +
            "  execute immediate 'select max(' || v_auto_key || ') from ' || v_tablename\n" +
            "    into db_now_max;\n" +
            "  execute immediate 'select ' || v_seqname || '.nextval from dual'\n" +
            "      into cur_next;\n" +
            "  if (db_now_max > cur_next) then\n" +
            "    tsql := 'alter sequence ' || v_seqname || ' increment by ' || (db_now_max-cur_next);\n" +
            "    execute immediate tsql;\n" +
            "    execute immediate 'select ' || v_seqname || '.nextval from dual'\n" +
            "      into cur_next;\n" +
            "    tsql := 'alter sequence ' || v_seqname || ' increment by 1';\n" +
            "    execute immediate tsql;\n" +
            "  end if;\n" +
            "end proc_seq_to_safe;";
    public List<String> getPreInitSql(Table table) {
        List<String> preSqlList = new ArrayList<String>();
        String baseSql = "ALTER TABLE %s DISABLE ALL TRIGGERS";
        String preSql = String.format(baseSql,table.getNameWithOutSchema());
        preSqlList.add(preSql);
        return preSqlList;
    }

    public List<String> getPostInitSql(Table table) throws SQLException {
        List<String> postSqlList = new ArrayList<String>();
        //存储过程只加一次
        if(procSql.length()==0){
            procSql =PROC_AUTO_INCREMENT_SQL;
            String from = DataBaseUtil.fromSourceLocal.get();
            if("tool".equals(from)){
                procSql += "\n/\n";
            }
            postSqlList.add(procSql);
        }

        String primaryValField ="";
        for (TableField field : table.getFieldList()) {
            //自增长主键
            if (field.getPrimary() && field.isAutoIncrease()) {
                StandardField stdField = MetadataUtil
                        .getStandardField(field.getStandardFieldId(), this
                                .getClass().getClassLoader());
                primaryValField = DataBaseUtil.getDataBaseName(stdField.getName());
                break;
            }
        }
        if(primaryValField.length()>0){
            String seqName = "SEQ_" + table.getNameWithOutSchema().toUpperCase();
            postSqlList.add(String.format("call proc_seq_to_safe('%s','%s','%s')",seqName,
                    table.getNameWithOutSchema().toUpperCase(),primaryValField.toUpperCase()));
        }
        return postSqlList;
    }

}
